﻿// 菜单.cpp : 定义应用程序的入口点。
//

#include "pch.h"
#include "framework.h"
#include "菜单.h"

#define MAX_LOADSTRING 100


/*
//1.系统菜单
        //1.1获取系统菜单
            g_hSystemMenu = GetSystemMenu(hWnd, false);

            //增加和修改的顺序无所谓的
        //1.2修改菜单项
            DeleteMenu(g_hSystemMenu, 4, MF_BYPOSITION);  //  MF_BYPOSITION：  指示 uPosition 为菜单项提供从零开始的相对位置。也就是相对位置，菜单项的第一个项为零位置，删除相对于零位置的相对位置的项
        //2.11增加
            AppendMenu(g_hSystemMenu, MF_STRING, 1000, L"李琼懿");   //  MF_STRING:  指定菜单项是文本字符串; lpNewItem 参数是指向字符串的指针。
            AppendMenu(g_hSystemMenu, MF_SEPARATOR, 1001,NULL);     //  MF_SEPARATOR:   绘制一条水平分割线。 此标志仅在下拉菜单、子菜单或快捷菜单中使用。 该行不能灰显、禁用或突出显示。 忽略 lpNewItem 和 uIDNewItem 参数。
            AppendMenu(g_hSystemMenu, MF_STRING |MF_GRAYED, 1002, L"李飞");    //  MF_GRAYED:  禁用菜单项并将其灰显，以便无法选择它。
            AppendMenu(g_hSystemMenu, MF_STRING, 1003, L"&李淇\tctrl+L");       //加快捷键的方法

    //生成的效果很明显，运行很可观

2.右键菜单  弹出式菜单
        2.1创建菜单
            CreatePopupMenu
        2.2修改菜单项（菜单可当成菜单项-子菜单）
            2.21增加      AppendMenu
            2.22删除      DeleteMenu
        2.3菜单项对应的消息处理
            2.31如何弹出
                WM_RBUTTONUP
                WM_CONTEXTMENU
                TrackPopMenu
            2.32响应
                WM_COMMAND

3.顶层菜单
    标题下边    工具栏上边

    编程模型:
        1.创建顶层菜单    CreateMenu
        2.创建弹出式菜单（顶层菜单的菜单项  子菜单） CreatePopupMenu
        3.给弹出式菜单添加菜单项   AppendMenu
        4.设置弹出式菜单为顶层菜单的菜单项
        5.设置顶层菜单显示
        6.获取当前顶层菜单句柄    GetMenu 通过窗口句柄获取
        7.获取菜单项句柄   通过菜单句柄获取    GetSubMenu



*/


















// 全局变量:
HINSTANCE hInst;                                // 当前实例
WCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名

HMENU g_hSystemMenu;
HMENU g_hPopupMenu;


// 此代码模块中包含的函数的前向声明:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);


void OnCreate(HWND hWnd);


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: 在此处放置代码。

    // 初始化全局字符串
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_MY, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY));

    MSG msg;

    // 主消息循环:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  函数: MyRegisterClass()
//
//  目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = NULL;   // MAKEINTRESOURCEW(IDC_MY);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目标: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中，我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // 将实例句柄存储在全局变量中

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目标: 处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
#if 0
    case WM_KEYDOWN:
        TrackPopupMenu(g_hPopupMenu, TPM_LEFTALIGN, 100, 100, 0, hWnd, NULL);   //在指定位置显示快捷菜单，并跟踪菜单上的项目选择。 快捷菜单可在屏幕上的任意位置显示。
            //  TPM_LEFTALIGN:  定位快捷菜单，使其左侧与 x 参数指定的坐标对齐。
#endif
#if 0
    case WM_RBUTTONUP:
    {
        //获取窗口坐标：
        int x = LOWORD(lParam);
        int y = HIWORD(lParam);

        //窗口坐标转屏幕坐标
        POINT p = { 0 };
        p.x = x;
        p.y = y;
        ClientToScreen(hWnd, &p);

        TrackPopupMenu(g_hPopupMenu, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);
    }
        
        break;
#endif
    case WM_CONTEXTMENU:
    {
        //获取窗口坐标：
        int x = LOWORD(lParam);
        int y = HIWORD(lParam);

        TrackPopupMenu(g_hPopupMenu, TPM_LEFTALIGN, x, y, 0, hWnd, NULL);
    }

    break;

    case WM_SYSCOMMAND:
        switch (LOWORD(wParam))
        {
        case 1000:      //点击菜单项李的李琼懿 运行
            MessageBox(NULL, L"运行李琼懿",L"我去",NULL);
            EnableMenuItem(g_hSystemMenu,1002, MF_ENABLED); //使能菜单项     启用、禁用或灰显指定的菜单项
                //  MF_ENABLED:指示菜单项已启用并从灰显状态还原，以便可以选择菜单项。
            break;
        case 1002:      //当前该菜单项是灰显，在不运行case 1000 时 该项也是不能运行的
            MessageBox(NULL, L"八嘎压路", L"阿里嘎多", NULL);   
            break;
        case 1003:
            break;

        default:                //注意 在Win32中 default 不能用break 会卡死
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;

    case WM_CREATE:
        OnCreate(hWnd);
        break;


    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择:
            switch (wmId)
            {
            case 2000:
                MessageBox(NULL, L"Monday", L"right", NULL);
                break;
            case 2001:
                MessageBox(NULL, L"Tday", L"right", NULL);
                break;
            case 2002:
                MessageBox(NULL, L"Wday", L"right", NULL);
                break;
            case 2003:
                MessageBox(NULL, L"Tday", L"right", NULL);
                break;
            case 2004:
                MessageBox(NULL, L"Fday", L"right", NULL);
                break;
            case 2005:
                MessageBox(NULL, L"Sday", L"right", NULL);
                break;
            case 2006:
                MessageBox(NULL, L"Sunday", L"right", NULL);
                break;


            case 3001:
                //通过窗口句柄去获取：
                //EnableMenuItem(GetSubMenu(GetMenu(hWnd),0), 3001, MF_GRAYED);



                MessageBox(NULL, L"3001", L"顶层", NULL);
                break;
            case 3002:
                MessageBox(NULL, L"3002", L"顶层", NULL);
                break;
            case 3003:
                MessageBox(NULL, L"3003", L"顶层", NULL);
                break;
            case 3004:
                MessageBox(NULL, L"3004", L"顶层", NULL);
                break;




            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}


void OnCreate(HWND hWnd)
{
    //1.系统菜单
        //1.1获取系统菜单
    g_hSystemMenu = GetSystemMenu(hWnd, false);

        //1.2修改菜单项
    //DeleteMenu(g_hSystemMenu, 4, MF_BYPOSITION);  //  MF_BYPOSITION：  指示 uPosition 为菜单项提供从零开始的相对位置。也就是相对位置，菜单项的第一个项为零位置，删除相对于零位置的相对位置的项
        //2.11增加
    AppendMenu(g_hSystemMenu, MF_STRING, 1000, L"李琼懿");   //  MF_STRING:  指定菜单项是文本字符串; lpNewItem 参数是指向字符串的指针。
    AppendMenu(g_hSystemMenu, MF_SEPARATOR, 1001,NULL);     //  MF_SEPARATOR:   绘制一条水平分割线。 此标志仅在下拉菜单、子菜单或快捷菜单中使用。 该行不能灰显、禁用或突出显示。 忽略 lpNewItem 和 uIDNewItem 参数。
    AppendMenu(g_hSystemMenu, MF_STRING |MF_GRAYED, 1002, L"李飞");    //  MF_GRAYED:  禁用菜单项并将其灰显，以便无法选择它。
    AppendMenu(g_hSystemMenu, MF_STRING, 1003, L"&李淇\tctrl+L");       //加快捷键的方法

    //生成的效果很明显，运行很可观


    //2.右键菜单  弹出式菜单
    //    2.1创建菜单
    g_hPopupMenu =  CreatePopupMenu();
    //    2.2修改菜单项（菜单可当成菜单项 - 子菜单）
    //    2.21增加
    AppendMenu(g_hPopupMenu, MF_STRING, 2000, L"星期一");
    AppendMenu(g_hPopupMenu, MF_STRING, 2001, L"星期二");
    AppendMenu(g_hPopupMenu, MF_STRING, 2002, L"星期三");
    AppendMenu(g_hPopupMenu, MF_STRING, 2003, L"星期四(&T)\tCtrl+T");      //生成快捷键
    AppendMenu(g_hPopupMenu, MF_STRING, 2004, L"星期五");
    AppendMenu(g_hPopupMenu, MF_STRING, 2005, L"星期六");
    AppendMenu(g_hPopupMenu, MF_STRING, 2006, L"星期七");





    // 顶层菜单：
    //1.创建顶层菜单
    HMENU hTop = CreateMenu();
    //2.创建弹出式菜单（顶层菜单的菜单项  子菜单） CreatePopupMenu
    HMENU hFile = CreatePopupMenu();
    HMENU hEdit = CreatePopupMenu();
    HMENU hView = CreatePopupMenu();
    HMENU hProj = CreatePopupMenu();

    //4.设置弹出式菜单为顶层菜单的菜单项
    AppendMenu(hTop, MF_POPUP, (UINT_PTR)hFile, L"文件");
    AppendMenu(hTop, MF_POPUP, (UINT_PTR)hEdit, L"编辑");
    AppendMenu(hTop, MF_POPUP, (UINT_PTR)hView, L"视图");
    AppendMenu(hTop, MF_POPUP, (UINT_PTR)hProj, L"项目");

    //3.给弹出式菜单添加菜单项   AppendMenu
    HMENU hNew = CreatePopupMenu();
    AppendMenu(hNew, MF_STRING, 3001, L"项目(&c)\tCtrl+l");
    AppendMenu(hNew, MF_STRING, 3002, L"网站");
    AppendMenu(hNew, MF_STRING, 3003, L"团队项目(&v)\tCtrl+v");
    AppendMenu(hNew, MF_STRING, 3004, L"文件");

    AppendMenu(hFile, MF_POPUP, (UINT_PTR)hNew, L"新建");

   
    //5.设置顶层菜单显示
    SetMenu(hWnd, hTop);
    //6.获取当前顶层菜单句柄    GetMenu 通过窗口句柄获取
    //7.获取菜单项句柄   通过菜单句柄获取    GetSubMenu


}